#include <UnitTest++.h>
#include <string>
#include "gTree.h"

struct GTreeFixture {

    GTreeFixture() {
        tree = new GTree<string>("root");
    }

    ~GTreeFixture() {
        delete tree;
        tree = 0;
    }

    void populateTree() {
        tree->insert("root", "tmp");
        tree->insert("tmp", "dir1");
        tree->insert("tmp", "dir2");
        tree->insert("dir1", "abc");
        tree->insert("dir2", "ccc");
        tree->insert("ccc", "cd1");
        tree->insert("ccc", "cd2");
        tree->insert("cd2", "dgw");
        tree->insert("cd2", "sdfe");
        tree->insert("tmp", "623t");
    }

    GTree<string>* tree;
};

TEST_FIXTURE(GTreeFixture, TestSize) {

    tree->insert("root", "src");
    int expectedSize = 2;
    CHECK_EQUAL(expectedSize, tree->size());
}

TEST_FIXTURE(GTreeFixture, TestSetRoot) {
    tree->setRoot(new GTreeNode<string>("./"));
    GTreeNode<string>& rootNode = tree->search("./");

    string expectedRootElement = "./";
    CHECK_EQUAL(expectedRootElement, rootNode.element_);
}

TEST_FIXTURE(GTreeFixture, TestInsertinRoot) {
    tree->insert("root", "tmp");
    GTreeNode<string>& tmp = tree->search("tmp");
    string expectedElement = "tmp";
    CHECK_EQUAL(expectedElement, tmp.element_);
}

TEST_FIXTURE(GTreeFixture, TestInsertInOtherNode) {
    populateTree();
    int expectedSize = 11;
    CHECK_EQUAL(expectedSize, tree->size());
}

TEST_FIXTURE(GTreeFixture, InsertionWithNonExistingParent) {
    populateTree();
    try {
        tree->insert("blabla", "new_element");
        CHECK(false);
    } catch (NonInitializedReference& e) {
        cout << e.what() << " insertion with non-existing parent" << endl;
        CHECK(true);
    }
}

TEST_FIXTURE(GTreeFixture, TestSearch) {
    populateTree();
    try {
        GTreeNode<string>& cd2 = tree->search("cd2");
        string cd2Value = "cd2";
        CHECK_EQUAL(cd2Value, cd2.element_);
    } catch (NonInitializedReference& e) {
        cout << e.what() << " test search" << endl;
        CHECK(false);
    }
}

TEST_FIXTURE(GTreeFixture, TestRemoveRoot) {
    tree->remove("root");
    int expectedSize = 0;
    CHECK_EQUAL(expectedSize, tree->size());
}

TEST_FIXTURE(GTreeFixture, TestRemoveNode) {
    populateTree();
    tree->remove("cd2");
    int expectedSize = 8;
    CHECK_EQUAL(expectedSize, tree->size());
}

TEST_FIXTURE(GTreeFixture, TestRemoveLeaf) {
    populateTree();
    tree->remove("623t");
    int expectedSize = 10;
    CHECK_EQUAL(expectedSize, tree->size());
}

TEST(TestReturningNonExistentRoot) {
    GTree<char> emptytree;
    try {
        GTreeNode<char>& uninitialized = emptytree.getRoot();
        CHECK(false);
    } catch (NonInitializedReference& e) {
        cout << e.what() << " test returning non-existent root" << endl;
        CHECK(true);
    }
}
